package com.example.myapplication.net.repository;

import com.example.myapplication.bean.LoginDetailBean;
import com.example.myapplication.bean.SendPhoneVerifyCodeBean;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.net.NetManager;
import ohos.utils.zson.ZSONReader;
import ohos.utils.zson.ZSONWriter;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author geyao
 * @date 2021/7/6
 * des:
 */
public class MainRepository implements IMainRepository {
    private final Context context;

    public MainRepository(Context context) {
        this.context = context;
    }

    @Override
    public boolean isNewAccount(String phoneNum) throws Exception {
        log("ThreadId2: " + Thread.currentThread().getId());
        HttpURLConnection connection = null;
        NetManager netManager = NetManager.getInstance(context);
        if (netManager == null) {
            throw new Exception("无法获取到NetManager");
        }
        if (!netManager.hasDefaultNet()) {
            throw new Exception("无法获取到DefaultNet");
        }
        URL url = new URL("https://icbc.jdd966.com/cobrandedcard-app/app/appUser/findUserCountByPhone");
        URLConnection urlConnection = netManager.getDefaultNet().openConnection(url, Proxy.NO_PROXY);
        if (urlConnection instanceof HttpURLConnection) {
            connection = (HttpURLConnection) urlConnection;
        }
        connection.setRequestMethod("POST");
        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);

        connection.setDoOutput(true);
        connection.setDoInput(true);

        connection.setUseCaches(false);

        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("User-Agent", getUserAgent());
        connection.setRequestProperty("version", "1.0.0");
        connection.setRequestProperty("x-access-token", "");

        connection.connect();

        String params = "phoneNum" + "=" + phoneNum;
        connection.getOutputStream().write(params.getBytes());
        int code = connection.getResponseCode();
        SendPhoneVerifyCodeBean bean;
        if (code == 200) {
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, StandardCharsets.UTF_8));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line).append("\n");
            }
            String msg = builder.toString();

            log("isNewAccount请求结果: " + msg);
            bean = new SendPhoneVerifyCodeBean();
            try (ZSONReader zsonReader = new ZSONReader(new StringReader(msg))) {
                zsonReader.startObject();
                while (zsonReader.hasNext()) {
                    switch (zsonReader.readName()) {
                        case "msg":
                            String msg1 = zsonReader.readString();
                            bean.setMsg(msg1);
                            break;
                        case "code":
                            bean.setCode(zsonReader.readString());
                            break;
                        case "data":
                            bean.setData(zsonReader.readString());
                            break;
                        default:
                            break;
                    }
                }
                zsonReader.endObject();
            }
        } else {
            throw new Exception("服务器响应结果: " + code);
        }
        if (connection != null) {
            connection.disconnect();
        }
        return bean != null && "0".equals(bean.getCode());
    }

    @Override
    public boolean sendPhoneVerifyNum(String phoneNum) throws Exception {
        HttpURLConnection connection = null;
        NetManager netManager = NetManager.getInstance(context);
        if (netManager == null) {
            throw new Exception("无法获取到NetManager");
        }
        if (!netManager.hasDefaultNet()) {
            throw new Exception("无法获取到DefaultNet");
        }
        URL url = new URL("https://icbc.jdd966.com/cobrandedcard-app/app/sign/appUser/sendTelRandom");
        URLConnection urlConnection = netManager.getDefaultNet().openConnection(url, Proxy.NO_PROXY);
        if (urlConnection instanceof HttpURLConnection) {
            connection = (HttpURLConnection) urlConnection;
        }
        connection.setRequestMethod("POST");
        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);

        connection.setDoOutput(true);
        connection.setDoInput(true);

        connection.setUseCaches(false);

        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("User-Agent", getUserAgent());
        connection.setRequestProperty("version", "1.0.0");
        connection.setRequestProperty("x-access-token", "");

        connection.connect();

        String params = "MOBILE" + "=" + phoneNum
                + "&timestamp" + "=" + currentDateString()
                + "&version" + "=" + "3.0.0";
        params += "&sign=" + sign("/app/sign/appUser/sendTelRandom?" + params);
        log("params: " + params);
        connection.getOutputStream().write(params.getBytes());

        String msg = "";
        String code = "";
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, StandardCharsets.UTF_8));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line).append("\n");
            }
            String responseStr = builder.toString();
            log("sendPhoneVerifyNum请求结果: " + responseStr);
            ZSONReader zsonReader = new ZSONReader(new StringReader(responseStr));
            zsonReader.startObject();
            while (zsonReader.hasNext()) {
                switch (zsonReader.readName()) {
                    case "msg":
                        msg = zsonReader.readString();
                        break;
                    case "code":
                        code = zsonReader.readString();
                        break;
                    default:
                        break;
                }
            }
            zsonReader.endObject();
        } else {
            throw new Exception("服务器响应结果: " + code);
        }
        if (connection != null) {
            connection.disconnect();
        }
        if ("10001".equals(code)) {
            return true;
        }
        throw new Exception(msg);
    }

    @Override
    public LoginDetailBean login(String phoneNum, String verifyCode) throws Exception {
        HttpURLConnection connection = null;
        NetManager netManager = NetManager.getInstance(context);
        if (netManager == null) {
            throw new Exception("无法获取到NetManager");
        }
        if (!netManager.hasDefaultNet()) {
            throw new Exception("无法获取到DefaultNet");
        }
        URL url = new URL("https://icbc.jdd966.com/cobrandedcard-app/app/sign/appUser/loginBySmscode");
        URLConnection urlConnection = netManager.getDefaultNet().openConnection(url, Proxy.NO_PROXY);
        if (urlConnection instanceof HttpURLConnection) {
            connection = (HttpURLConnection) urlConnection;
        }
        connection.setRequestMethod("POST");
        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);

        String myUUID = getMyUUID();
        String time = currentDateString();
        String signStr = "/app/sign/appUser/loginBySmscode"
                + "?LOGIN_TEL" + "=" + phoneNum
                + "&RANDOM" + "=" + verifyCode
                + "&clientId" + "=" + myUUID
                + "&timestamp" + "=" + time
                + "&version" + "=" + "3.0.0";
        log("signStr: " + signStr);

        StringWriter stringWriter = new StringWriter();
        try (ZSONWriter writer = new ZSONWriter(stringWriter)) {
            writer.startObject();

            writer.writeName("LOGIN_TEL");
            writer.writeString(phoneNum);
            writer.writeName("RANDOM");
            writer.writeString(verifyCode);
            writer.writeName("clientId");
            writer.writeString(myUUID);
            writer.writeName("timestamp");
            writer.writeString(time);
            writer.writeName("version");
            writer.writeString("3.0.0");
            writer.writeName("sign");
            writer.writeString(sign(signStr));

            writer.endObject();
            writer.flush();
        }
        String params = stringWriter.toString();
        log("params: " + params);

        connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
        connection.setRequestProperty("Content-Length", String.valueOf(params.length()));
        connection.setRequestProperty("User-Agent", getUserAgent());
        connection.setRequestProperty("version", "1.0.0");
        connection.setRequestProperty("x-access-token", "");


        connection.connect();
        DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
        outputStream.writeBytes(params);

        LoginDetailBean result = new LoginDetailBean();
        String msg = "";
        String code = "";
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            InputStream is = connection.getInputStream();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, StandardCharsets.UTF_8));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line).append("\n");
            }
            String responseStr = builder.toString();
            log("login请求结果: " + responseStr);
            ZSONReader zsonReader = new ZSONReader(new StringReader(responseStr));
            zsonReader.startObject();
            while (zsonReader.hasNext()) {
                switch (zsonReader.readName()) {
                    case "msg":
                        msg = zsonReader.readString();
                        break;
                    case "code":
                        code = zsonReader.readString();
                        break;
                    case "data":
                        String data = zsonReader.readString();
                        ZSONReader dataReader = new ZSONReader(new StringReader(data));
                        dataReader.startObject();
                        while (dataReader.hasNext()) {
                            switch (dataReader.readName()) {
                                case "NETNAME":
                                    result.setNetName(dataReader.readString());
                                    break;
                                case "POINTS_FARE":
                                    result.setPointsFare(dataReader.readInt());
                                    break;
                                case "CUST_TEL":
                                    result.setTel(dataReader.readString());
                                    break;
                                case "PROMOTERINFO_ID":
                                    result.setPromoterInfoId(dataReader.readString());
                                    break;
                                case "occupation":
                                    result.setOccupation(dataReader.readString());
                                    break;
                                case "ICONPIC":
                                    result.setIconPicture(dataReader.readString());
                                    break;
                                case "WX_ID":
                                    result.setWxId(dataReader.readString());
                                    break;
                                case "accessToken":
                                    result.setAccessToken(dataReader.readString());
                                    break;
                                case "logined":
                                    result.setLoginStatus(dataReader.readBoolean());
                                    break;
                                case "FIRSTLOGIN":
                                    result.setFirstLogin(dataReader.readString());
                                    break;
                                case "APPSEX":
                                    result.setAppSex(dataReader.readString());
                                    break;
                                case "accountOrgNo":
                                    result.setAccountOrgNo(dataReader.readString());
                                    break;
                                case "ISPROMOTER":
                                    result.setIsPromoter(dataReader.readString());
                                    break;
                                case "CARDCUST_ID":
                                    result.setCardId(dataReader.readString());
                                    break;
                                case "APPBIRTH":
                                    result.setAppBirth(dataReader.readString());
                                    break;
                                case "tokenType":
                                    result.setTokenType(dataReader.readString());
                                    break;
                                case "WX_UNION_ID":
                                    result.setWxUnionId(dataReader.readString());
                                    break;
                                case "refreshToken":
                                    result.setRefreshToken(dataReader.readString());
                                    break;
                                default:
                                    break;
                            }
                        }
                        dataReader.endObject();
                        break;
                    default:
                        break;
                }
            }
            zsonReader.endObject();
        } else {
            throw new Exception("服务器响应结果: " + code);
        }
        log("msg: " + msg);
        log("code: " + code);
        log("bean: " + result.toString());
        if (connection != null) {
            connection.disconnect();
        }
        if ("10001".equals(code)) {
            return result;
        }
        throw new Exception(msg);
    }

    /**
     * 返回正确的UserAgent
     */
    public static String getUserAgent() {
        String userAgent;
        StringBuilder sb = new StringBuilder();
        userAgent = System.getProperty("http.agent");//Dalvik/2.1.0 (Linux; U; Android 6.0.1; vivo X9L Build/MMB29M)
        if (userAgent != null) {
            for (int i = 0, length = userAgent.length(); i < length; i++) {
                char c = userAgent.charAt(i);
                if (c <= '\u001f' || c >= '\u007f') {
                    sb.append(String.format("\\u%04x", (int) c));
                } else {
                    sb.append(c);
                }
            }
        }

        return sb.toString();
    }

    /**
     * 获取退款进度列表条目时间
     *
     * @return 格式化日期
     */
    private static String currentDateString() {
        //返回系统时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
        format.setTimeZone(TimeZone.getTimeZone("GMT+08"));
        Date msgDate = new Date();
        return format.format(msgDate);
    }

    /**
     * 签名信息
     *
     * @param content:签名的参数内容
     * @return 签名后的字符串
     */
    private static String sign(String content) {
        String charset = "utf-8";
        String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIrRLDgUd2KN4+4CpP+B2/iYGMG8Rroo1kQSlxHvi0kXI1bR12jo2xEgIsEj4oq5MFJNWoVX6c6q35jjNgkcNdRTIuUbXXokrbhiT98usV7ofzB9sdcG5k+G8d4pYEy0Y9bv6uixfkIWO0Gcyi+4nF5zsDaKa7nRzWLxrufaqtJpAgMBAAECgYArN3Gvx9dfDFOAfrxFe3UzEI7siaPvQtVp/eugPtY7HAP5fHy2gX/p9fo77OMTUxITHVfoGXWFzLatz1a8QVcUXDM0I/9N5nGBCmpviQC+w/j/E08hpus8BAh9lRb8vMoMgLgx3Gb1Tc9rmIOiXtiZIVo28F28eponBPPgwdlDvQJBAM3y8eODfut5gTtLvrN+6SM4xT6Zbbn5l0mqiU9HO+28zwQkVRp5gxzc+9MkDX2zzzR7mnD7RrWp+Cq8VB27+u8CQQCsjaKzT2L0QI5H7xX8fgJtj45JcbXGXsY54nHHSFU5P50MDQJS48AoDBVhqupm1iP+iHV4zUaM95g1iiaOUegnAkBj+Zmevkiweo1XgY+ThvoZ1Qc7OjPf4d+lLRn22DepUsyT0CdX8MDLFCNS/d9mtBDUA2SXkANlUJtd84pJ3OUVAkBCIYIykIFPNRKSlRnrC+woSzVwBmlxHk+ATb3nb1xiNXQd8zppxCmX75GePd/aC8X9vhSveJTKX/XwxwKh1thPAkBlvz74WAzgI0LwSiiIPM00m7xfdOjpUTRIZrXx1SCrBiZFXGkFIKBaGAAnoqQ8PcZOCfE5zyeUxGklyc27O61R";
        try {
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIVATE_KEY));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            Signature signature = Signature.getInstance("SHA1WithRSA");
            signature.initSign(priKey);
            signature.update(content.getBytes(charset));
            byte[] signed = signature.sign();
            return Base64.getEncoder().encodeToString(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获得独一无二的设备信息ID
     */
    public static String getMyUUID() {
        return UUID.randomUUID().toString();
    }

    protected void log(String str) {
        HiLogLabel hiLogLabel = new HiLogLabel(HiLog.LOG_APP, 0x00202, MainRepository.class.getSimpleName());
        HiLog.info(hiLogLabel, str);
    }
}
